昨天我們一起瞭解了什麼是NLU,為什麼Chatbot需要NLU。
那我們一樣來個小程式,來介紹我們如何使用BERT來觀察語言模型是怎麼理解我們所說的話~
為了方便解釋,我們將使用ConvLab模組裡的BERTNLU類別來做說明。
首先,直接把北京清大開發的ConvLab package抓下來~
git clone --depth 1 https://github.com/ConvLab/ConvLab-3.git && cd ConvLab-3 && pip install -e .
ConvLab是一個用於簡易開發任務導向對話系統的平台,在後面的幾天會詳細介紹
接著,我們載入convlab.nlu.jointBERT.crosswoz.nlu
裡的 BERTNLU
表示使用以crosswoz
訓練的 jointBERT
模型來做自然語言理解任務。
from convlab.nlu.jointBERT.crosswoz.nlu import BERTNLU
而
crosswoz
為專門訓練TOD對話系統的中文語料集,這個在後面幾天也會介紹~
然後我們就可以載入模型並預測
這裡必需要注意,config_file
和model_file
需要跟著mode
參數,
cross_nlu = BERTNLU(
mode='all', # 要辨識使用者/系統或者全部意圖
config_file='crosswoz_all_context.json', # 使用設定檔
model_file='https://huggingface.co/ConvLab/ConvLab-2_models/resolve/main/bert_crosswoz_all_context.zip' # 選擇相應的BERT model
)
# 預測輸出
print(cross_nlu.predict("北京布提克精品酒店酒店是什么类型,有健身房吗?"))
mode
表示要辨識哪個角色的意圖,有使用者usr
、系統(chatbot)sys
和全部(使用者和系統)all
輸出為一連串的串列,格式是[意圖, 領域, 槽名稱, 值]
就長這樣子~
[
['General', 'greet', 'none', 'none'],
['Request', '酒店', '酒店类型', ''],
['Inform', '酒店', '酒店设施-健身房', '是'],
['Inform', '酒店', '名称', '北京布提克精品酒店']
]
我們來講解串列裡各個值代表的含義,
意圖
: 代表話語中包含的意圖,Ex. Request表請求某項資訊、Inform表提供資訊。領域
: 代表話語提到哪個對話主題,如: 酒店、觀光景點等槽名稱
: 代表對話中提到的實體,如: 名稱、設施、類型...等等值
: 槽名稱的值。JointBERT
模型我們回顧昨天提到的JointBERT模型,
JointBERT由BERT為基底,分成Intent Classification
和Slot Filling
Intent Classification
做意圖分類,而Slot Filling
辨識槽名稱及槽值
對應到程式就如下:
# BERT based model
# "hfl/chinese-bert-wwm-ext"
self.bert = BertModel.from_pretrained(model_config['pretrained_weights'])
self.dropout = nn.Dropout(model_config['dropout'])
# Intent Classification-分類話語意圖
self.intent_hidden = nn.Linear(self.bert.config.hidden_size, self.hidden_units)
self.intent_classifier = nn.Linear(self.hidden_units, self.intent_num_labels)
# Slot Filling-辨識話語中有意義之字詞
self.slot_hidden = nn.Linear(self.bert.config.hidden_size, self.hidden_units)
self.slot_classifier = nn.Linear(self.hidden_units, self.slot_num_labels)
以下是我節錄
JointBERT
類別裡的模型片段程式碼
Reference.
GitHub-ConvLab/ConvLab-3